//
//  YLStoreKitV2Manager.swift
//  YLPaymentKit
//
//  Created by changhe on 2025/4/12.
//

import Foundation
import StoreKit
import UIKit
import ObjectiveC
import CommonCrypto

/// StoreKit v2 管理器 - 处理iOS 15及更高版本的内购
@available(iOS 15.0, *)
public class YLStoreKitV2Manager: YLStoreKitManagerProtocol {
	
    // MARK: - YLStoreKitManagerProtocol 实现
    
    /// 是否可用
    public var isAvailable: Bool {
        return true // StoreKit 2 总是可用
    }

    /// 获取商品信息
    public func fetchProducts(productIds: [String], completion: @escaping (Result<[Any], Error>) -> Void) {
        Task {
            do {
                let products = try await fetchProducts(productIds: productIds)
                await MainActor.run {
                    completion(.success(products))
                }
            } catch {
                await MainActor.run {
                    completion(.failure(error))
                }
            }
        }
    }
    
    /// 购买商品
    /// - Parameters:
    ///   - productId: 苹果商品ID
    ///   - orderId: 订单ID
    ///   - completion: 完成回调
    public func purchase(productId: String, orderId: String, completion: @escaping (YLPaymentResult) -> Void) {
        Task {
            do {
                // 获取产品信息
                let products = try await fetchProducts(productIds: [productId])
                
                guard let product = products.first else {
                    await MainActor.run {
                        completion(.failure(.productNotFound))
                    }
                    return
                }
				await purchaseProduct(product, orderId: orderId, completion: completion)
            } catch {
                await MainActor.run {
                    completion(.failure(.storeKitError(error)))
                }
            }
        }
    }
    

    /// 完成交易
    public func finishTransaction(_ transaction: Any) {
        if let transaction = transaction as? Transaction {
            Task {
                await transaction.finish()
            }
        }
    }
    
    // MARK: - 初始化
    
	init() { }
    
    // MARK: - 公共方法
	
    /// 获取商品信息
    public func fetchProducts(productIds: [String]) async throws -> [Product] {
        guard !productIds.isEmpty else {
            throw YLPaymentError.invalidParameters
        }
        
        return try await Product.products(for: Set(productIds))
    }
	
	/// 恢复购买
	public func restorePurchases(completion: @escaping (YLPaymentResult) -> Void) {

		let savedCompletion = completion
		
		Task { @MainActor in
			do {
				var foundTransaction = false
				
				try Task.checkCancellation()
				
				for await verificationResult in Transaction.currentEntitlements {
					if case .verified(let transaction) = verificationResult {
						var orderId = transaction.appAccountToken?.uuidString
						if let oid = orderId {
							orderId = YLOrderUUIDTransformer.fromUUID(oid)
						}
						await processTransaction(verificationResult, orderId: orderId, completion: savedCompletion)
						foundTransaction = true
						break
					}
				}
				
				if !foundTransaction {
					
					try await AppStore.sync()
					
					for await verificationResult in Transaction.currentEntitlements {
						if case .verified(let transaction) = verificationResult {
							var orderId = transaction.appAccountToken?.uuidString
							if let oid = orderId {
								orderId = YLOrderUUIDTransformer.fromUUID(oid)
							}
							await processTransaction(verificationResult, orderId: orderId, completion: savedCompletion)
							foundTransaction = true
							break
						}
					}
					
					if !foundTransaction {
						savedCompletion(.failure(.other("没有找到任何购买记录")))
					}
				}
			} catch let error {
				savedCompletion(.failure(.storeKitError(error)))
			}
		}
	}
	
	// 检查未完成交易的订单信息
	public func checkUnfinishedTransactions(completHandler: (([YLTransactionInfo])-> Void)?) {
		Task {
			var localTransactions: [YLTransactionInfo] = []
			
			for await result in Transaction.unfinished {
				guard case .verified(let transaction) = result else { continue }
				
				let transactionInfo = YLTransactionInfo(storeKitTransaction: transaction)
				
				localTransactions.append(transactionInfo)
			}
			
		   let transactions = localTransactions
		   
		   await MainActor.run {
			   completHandler?(transactions)
		   }
		}
	}
	
    /// 发起退款请求
    public func beginRefundRequest(for transactionId: UInt64, in scene: UIWindowScene) async throws -> Transaction.RefundRequestStatus {
        return try await Transaction.beginRefundRequest(for: transactionId, in: scene)
    }
    
    /// 购买商品
    private func purchaseProduct(_ product: Product, orderId: String?, completion: @escaping (YLPaymentResult) -> Void) async {
		
		Task {
			do {
				// 创建购买选项
				var options: Set<Product.PurchaseOption> = []
				
				// 保存订单ID的方法
				if let orderId = orderId {
					let haxUuid = YLOrderUUIDTransformer.toUUID(orderId)
					if let uuid = UUID(uuidString: haxUuid) {
						options.insert(.appAccountToken(uuid))
					}
				}
				
				// 发起购买
				let result = try await product.purchase(options: options)
				
				// 处理购买结果
				switch result {
				case .success(let verificationResult):
					await processTransaction(verificationResult, orderId: orderId, completion: completion)
					
				case .userCancelled:
					await MainActor.run {
						completion(.cancel)
					}
					
				case .pending:
					await MainActor.run {
						completion(.failure(.purchaseInProgress))
					}
					
				@unknown default:
					await MainActor.run {
						completion(.failure(.unknownError))
					}
				}
			} catch {
				await MainActor.run {
					handlePurchaseError(error, completion: completion)
				}
			}
		}
        
    }

    /// 处理交易
    private func processTransaction(_ verificationResult: VerificationResult<Transaction>, orderId: String?, completion: @escaping (YLPaymentResult) -> Void) async {
        if case .verified(let transaction) = verificationResult {

			var finalOrderId = orderId
            
            if finalOrderId == nil || finalOrderId?.isEmpty == true {
                if let appAccountToken = transaction.appAccountToken {
					finalOrderId = YLOrderUUIDTransformer.fromUUID(appAccountToken.uuidString)
                }
            }
            
			var transactionInfo = YLTransactionInfo(storeKitTransaction: transaction)
			transactionInfo.orderId = finalOrderId ?? ""
            
			let oid = finalOrderId ?? ""
			let info = transactionInfo
            // 调用支付结果回调
            await MainActor.run {
                completion(.success(YLPaymentResultData(
                    orderId: oid,
                    transactionId: transaction.id.description,
                    productId: transaction.productID,
                    transactionDate: transaction.purchaseDate,
                    originalTransactionId: transaction.originalID.description,
					transactionInfo: info,
					rawInfo: transaction
                )))
            }
        } else {
            await MainActor.run {
                completion(.failure(.transactionVerificationFailed))
            }
        }
    }
    
    /// 处理购买错误
    private func handlePurchaseError(_ error: Error, completion: @escaping (YLPaymentResult) -> Void) {
        // 提供更详细的错误处理
        if let paymentError = error as? YLPaymentError {
            completion(.failure(paymentError))
            return
        }
        
        // 处理StoreKit特定错误
        let nsError = error as NSError
        if nsError.domain == "com.apple.storekit" {
            switch nsError.code {
            case 2:
                completion(.failure(.sdkNotAvailable))
            case 3, 4, 5:
                completion(.cancel) // 用户取消
            default:
                completion(.failure(.other("StoreKit错误：\(nsError.localizedDescription) (代码: \(nsError.code)")))
            }
        } else {
            // 其他错误
            completion(.failure(.storeKitError(error)))
        }
    }

    /// 处理支付
    func handlePayment(params: YLPaymentParams, completion: @escaping (YLPaymentResult) -> Void) {
        // 检查参数类型
        guard let iapParams = params as? YLIAPParams else {
            completion(.failure(.invalidParameters))
            return
        }
		
        // 从参数中提取必要信息
        let productId = iapParams.productId
        let orderId = iapParams.orderId

        self.purchase(productId: productId, orderId: orderId, completion: completion)
    }
	

}
